import React, { Component } from 'react';
import { Select, Breadcrumb } from 'antd';
import { withRouter, Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import { connect } from 'react-redux';
import _ from 'lodash';

import { getOnedayTaskDetail, getOnedayTaskIpList, getTaskHistory } from '@api/task';
import Status from '../components/status';
import Info from '../components/info';
import OneDayTable from '../components/oneday-table';
import './index.less';
import { loadAssets } from '@api/asset';

const SelectOption = Select.Option;

class OnedatTaskDetail extends Component {
  static propTypes = {
    match: PropTypes.object,
    socketIO: PropTypes.object
  };
  constructor(props) {
    super(props);
    this.state = {
      page: 1,
      pageSize: 10,
      currentVulTime: '',
      task: {},
      onedayList: [],
      vulTimes: [],
      total: 0,
      statics: {},
      roundId: '',

      expandedRowKeys: [],
      updatedTaskTarget: false
    };
    this.taskId = props.match.params.id;
  }

  // eslint-disable-next-line
  UNSAFE_componentWillReceiveProps(nextProps) {
    let newTaskId = nextProps.match.params.id;
    if (newTaskId !== this.taskId) {
      this.taskId = newTaskId;
      this.loadDetail();
    }
  }

  componentDidMount() {
    this.loadDetail();
    this.bindSocketIO();
    this.onGetTaskHistory();
  }

  componentWillUnmount() {
    this.unbindSocketIO();
  }

  onGetTaskHistory = () => {
    getTaskHistory(this.taskId).then(res => {
      const vulTimes = get(res, 'data.data.list', []);
      const currentVulTime = _.get(vulTimes[0], 'lastEnd'); // 时间列表倒序排列
      this.setState({
        vulTimes,
        currentVulTime
      });
    });
  };

  loadDetail = () => {
    getOnedayTaskDetail(this.taskId).then(async res => {
      const task = get(res, 'data.data.task', {});
      // 兼容
      if (task.status === 'RUNNING') {
        task.taskParams.status = 'processing';
      }
      const roundId = get(task, '_id');
      task.targetCount = (await this.getAllSites()) || 0;
      this.setState(
        {
          task,
          roundId
        },
        this.loadOnedayList
      );
    });
  };

  getAllSites = () => {
    return loadAssets({})
      .then(res => {
        const count = _.get(res, 'data.data.count', 0);
        return count;
      })
      .catch(() => {
        return 0;
      });
  };

  hitTaskFilter = data => {
    // eslint-disable-next-line
    const { taskId } = data;
    return taskId === this.taskId;
  };

  bindSocketIO = () => {
    const { socketIO } = this.props;
    if (!socketIO) {
      return;
    }
    socketIO.on('task_handler', this.onSocketIOData, this.hitTaskFilter);
  };

  unbindSocketIO = () => {
    const { socketIO } = this.props;
    if (!socketIO) {
      return;
    }
    socketIO.cancel('task_handler', this.onSocketIOData);
  };

  onSocketIOData = (data, method) => {
    /* eslint-disable */
    switch (method) {
      case 'task_running':
      case 'task_stopped':
      case 'task_failed':
      case 'task_deleted':
      case 'task_finished':
        this.loadDetail();
        break;
      case 'task_progress':
        this.onSocketIODataProcess(data);
        break;
      default:
        break;
    }
    /* eslint-enable */
  };

  onSocketIODataProcess = data => {
    // eslint-disable-next-line
    const { progress, status } = data;
    const task = _.clone(this.state.task);
    if (status) {
      this.loadDetail();
      return;
    }
    task.progress.progress = progress;
    task.taskParams.status = 'processing';
    this.setState({ task });
  };

  loadOnedayList = () => {
    const { page, pageSize, roundId } = this.state;
    if (!roundId || !page || !pageSize) {
      return;
    }
    // eslint-disable-next-line
    getOnedayTaskIpList({ task_id: this.taskId, page, pageSize, roundId }).then(res => {
      const { list = [], statics = {}, count = 0 } = get(res, 'data.data', {});
      this.setState({ onedayList: list, statics, total: count, expandedRowKeys: [] });
    });
  };

  onCurrentTimeChange = (currentVulTime, current) => {
    this.setState(
      {
        currentVulTime: currentVulTime,
        roundId: _.get(current, 'key'),
        page: 1,
        pageSize: 10
      },
      this.loadOnedayList
    );
  };

  onTableChange = ({ current: page, pageSize }) => {
    this.setState(
      {
        page,
        pageSize
      },
      this.loadOnedayList
    );
  };

  updateTaskTargetTarget = (taskTarget = {}) => {
    this.setState({ task: Object.assign(this.state.task, taskTarget), updatedTaskTarget: true });
  };

  render() {
    const {
      page,
      pageSize,
      total,
      task,
      vulTimes,
      currentVulTime,
      onedayList,
      statics
    } = this.state;

    const pagination = {
      current: page,
      pageSize,
      total,
      showTotal: num => `共 ${num} 条`,
      showQuickJumper: true,
      showSizeChanger: true
    };

    return (
      <div className="task-manage-oneday">
        <div className="bread">
          <Breadcrumb>
            <Breadcrumb.Item>
              <Link to="/task-manage">任务管理</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>
              <span style={{ fontWeight: 600 }}>任务详情</span>
            </Breadcrumb.Item>
          </Breadcrumb>
        </div>
        <div className="tmo__top">
          <div className="tmo-status">
            <Status
              task={{
                ...task.taskParams,
                _id: task.taskOid,
                progress: task.progress,
                isDeleted: task.isDeleted
              }}
              enableProcess={false}
            />
          </div>
          <div className="tmo-info">
            <Info task={task} />
          </div>
        </div>
        <div className="tmo__bottom">
          <div className="tmo-result__header">
            <span className="value">漏洞扫描结果</span>
            <span className="label">时间</span>
            <Select value={currentVulTime} className="select" onChange={this.onCurrentTimeChange}>
              {vulTimes.map(vt => (
                <SelectOption value={_.get(vt, 'lastEnd')} key={_.get(vt, '_id')}>
                  {_.get(vt, 'lastEnd')}
                </SelectOption>
              ))}
            </Select>
          </div>
          <div className="tmo-result__info">
            {currentVulTime} 扫描到漏洞：一共{get(statics, 'total', 0)}个漏洞,其中严重
            {get(statics, 'fatal', 0)}个,高危{get(statics, 'high', 0)}个，中危
            {get(statics, 'middle', 0)}个，低危{get(statics, 'low', 0)}个。
          </div>
          <div className="tmo-result__table">
            <OneDayTable
              onedayList={onedayList}
              pagination={pagination}
              onTableChange={this.onTableChange}
            />
          </div>
        </div>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    socketIO: get(state, 'socketIO.socketIO', null)
  };
};

export default withRouter(connect(mapStateToProps)(OnedatTaskDetail));
